package com.mem.barrier;

import sun.misc.Unsafe;

import java.lang.reflect.Field;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockDemo implements Runnable {
    private static ReentrantLock lock = new ReentrantLock(true);

    @Override
    public void run() {
        while (true) {
            lock.lock();
            try {
                System.out.println(Thread.currentThread().getName() + " get lock");
                Thread.sleep(1000);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    }

    private volatile int field;
    private volatile Object obj;
    static long offset;
    static long offsetObj;
    static Unsafe uf;

    static {
        try {
            Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
            theUnsafe.setAccessible(true);
            uf = (Unsafe) theUnsafe.get(null);
            offset = uf.objectFieldOffset(ReentrantLockDemo.class.getDeclaredField("field"));
            offsetObj = uf.objectFieldOffset(ReentrantLockDemo.class.getDeclaredField("obj"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws Exception {
//        ReentrantLockDemo rtld = new ReentrantLockDemo();
//        Thread thread1 = new Thread(rtld);
//        Thread thread2 = new Thread(rtld);
//        thread1.start();
//        thread2.start();
        ReentrantLockDemo reentrentLockDemo = new ReentrantLockDemo();
        reentrentLockDemo.swap();
    }
    public void swap() {
        boolean ret = uf.compareAndSwapObject(this, offsetObj, null, "1");
        System.out.println("ReentrantLockDemo.swap: " + ret);
    }

}